home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume8 / graph+ / part01 next >
Encoding:
Internet Message Format  |  1987-03-01  |  60.0 KB

  1. Path: mirror!adelie!necntc!husc6!seismo!munnari!sources-request
  2. From: sources-request@munnari.oz
  3. Newsgroups: mod.sources
  4. Subject: v08i081:  Graph+, A Graph Plotting Program, Part01/03
  5. Message-ID: <1431@munnari.oz>
  6. Date: 28 Feb 87 07:35:08 GMT
  7. Sender: kre@munnari.oz
  8. Lines: 2167
  9. Approved: kre@munnari.oz.au
  10.  
  11. Submitted by: Alan Kent <ajk@goanna.oz.au>
  12. Mod.sources: Volume 8, Issue 81
  13. Archive-name: graph+/Part01
  14.  
  15. #! /bin/sh
  16. # This is a shell archive, meaning:
  17. # 1.  Remove everything above the #! /bin/sh line.
  18. # 2.  Save the resulting test in a file
  19. # 3.  Execute the file with /bin/sh (not csh) to create the files:
  20. #
  21. #        README
  22. #        graph+.1
  23. #        Makefile
  24. #        bar_graph
  25. #        best_fit
  26. #        graph.h
  27. #        yacc.y
  28. #
  29. # Created by ajk on Wed Feb 25 09:23:09 EST 1987
  30. #
  31. if test -f 'README'
  32. then
  33.     echo shar: will not over-write existing file "'README'"
  34. else
  35. echo extracting "'README'"
  36. sed 's/^X//' >README <<'SHAR_EOF'
  37. XA Graph Plot Program:
  38. X
  39. XI have found this program extremely useful for generating line plots from
  40. Xtables of data. It provides quite powerful operators to maniuplate and
  41. Xjoin different tables of numeric data. It does not do bar graphs, pie charts
  42. Xetc., although it could be modified to do so (and no, I am not volunteering!)
  43. X
  44. XIt can also be used as a desk calculator or to print tables of results
  45. Xon the screen rather than as a graph. I personally prefer it to using
  46. Xdc and bc quite often (but then I am probably biased). Just type graph+
  47. Xthen 'print 1/log(3);' etc. I also use it interactively to check data
  48. Xfiles, find how many entries have a column with values in a certain range
  49. Xand so on. For example
  50. X    data = read "datafile"
  51. X    print count ( data where $1 > 0 && $1 < 10)
  52. X
  53. XThe program here is not interactive like GNUPLOT but an alternative which
  54. Xprovides greater flexability in the preparation of data before it is plot
  55. X(I think). Since it can be used in a non-interactive fashion, it can
  56. Xbe used in makefiles (I use Makefiles to keep documents which include
  57. Xgraphs up to date).
  58. X
  59. XThis program requires lex and yacc, and at present has calls to ctime()
  60. Xand getenv() (although these last two calls are not critical). It also
  61. Xrequires the standard unix plot(3X) library. Output is in plot(5) format
  62. Xwhich must be fed through a filter program before it can be displayed.
  63. XThe maths library is used extensively to provide the same functions in
  64. Xgraph+, but the actual code only really needs log() and pow().
  65. X
  66. XI hope it is of some use to someone.
  67. X
  68. XAt the end of this file are instructions for patching this program
  69. Xfor your system.
  70. X
  71. XBrief History
  72. X=============
  73. X
  74. XAfter needing some graphs plotted and finding that the only really available
  75. Xcommand I could find was graph(1), I decided to write my own. I also found
  76. Xthat awk was too slow for my liking when trying to extract data from lots
  77. Xof files to be reformatted in some way. Thus graph+ was born. Graph+ requires
  78. Xa program (much like a shell script) to drive it. It allows files of data
  79. Xto be loaded as two dimensional arrays and then allows many commands to
  80. Xmanipulate the data. For example
  81. X
  82. X    data = read "data.file"
  83. X    graph data where $1 > 0 [ $2 , $3 + $4 ] dotted line label "data"
  84. X
  85. Xwill plot a graph of the data in the file data.file but will only plot
  86. Xpoints where the first column in the file has values greater than zero,
  87. Xand the data to plot will be column 2 (x) vs the sum of the values in
  88. Xcolumn 3 and 4 (y).
  89. X
  90. XWhen plotting the graph, different types of lines can be used (solid,
  91. Xdotted, dot dashed, short dashed, long dashed) or each point can be
  92. Xseparately marked (with triangles, squares, circles, crosses).
  93. XAll the scaling and numbering of the axis is done automatically
  94. Xalthough most values can be over-ridden.
  95. X
  96. XThe program also allows functions to be defined with sufficent power
  97. Xto do a least-squares best fit algorithm.
  98. X
  99. XThe software was not written for efficency (it can be memory hungry
  100. Xas all the table operations tend to make copies when performing the
  101. Xoperations) but I have not found memory to be a problem yet (well,
  102. Xnot on our vax anyway!)
  103. X
  104. XAll output is in standard plot(1) format as it uses the -lplot libraries.
  105. X
  106. XThis software should be fairly portable across UNIX systems although
  107. Xa little work may be required for other systems (like IBM PCs).
  108. X
  109. XCOMMON PROBLEMS
  110. X===============
  111. X
  112. XThe automatic scaling mechanism still does not always work correctly.
  113. XIt is actually very difficult to do properly. If strange things appear
  114. Xto be happening, try specifiying from and to on the xaxis and yaxis
  115. Xstatements (xaxis from 0 to 1000). Also, there can only be one xaxis
  116. Xand yaxis command per plot - multiple commands will ignore preceeding
  117. Xcommands.
  118. X
  119. XMost of the automatic features can be overriden manually.
  120. X
  121. X
  122. XPossible Patching Problems:
  123. X
  124. Xo   The file main.c contains a path name that needs to be patched.
  125. X    This is because the program looks in some special directories for
  126. X    predefined funtions (if you wish to install any). (See GLOB_LIB)
  127. X    The path can be defined in the Makefile instead.
  128. X
  129. Xo   The last function in main.c may also need to be re-written for your machine
  130. X    as it tries to determine what caused a floating exception. It will
  131. X    probably work without any alterations. It is patched for our VAX 11/750
  132. X    running BSD 4.2 at the moment.
  133. X
  134. Xo   The file main.c uses getenv() and the file yacc.y uses time(),
  135. X    ctime() and system() (for the shell statement).
  136. X
  137. Xo   The include statement may not work as it involves fiddling with yacc.
  138. X    At present it chews one token more than I really want it to.
  139. X
  140. Xo   If your library does not contain relevant maths functions, either
  141. X    just delete the code, insert a dummy function, or whatever. Note
  142. X    that the code assumes all math functions have extern double func();
  143. X    in <math.h> so if the function is not in the library, you will 
  144. X    probably have to add your own extern's where necessary.
  145. X
  146. Xo   dumpgrph.c needs to know the width of a character!! This of course
  147. X    changes per output device. If the macro LASER is defined, it seems
  148. X    to work ok with our apple laser printer (helvetica), otherwise
  149. X    it works for a tektronics emulator on a Sun we have here. The size
  150. X    of a character must be known so that centering and right justification
  151. X    can be done (for titles, numbers along axis etc).
  152. X
  153. Xo   -lplot should be used in the Makefile for the most general form
  154. X    of the program. Output can then be fed into plot(1) which re-maps
  155. X    it for differnt terminal types. If however there is only one terminal
  156. X    you are ever going to use it on (eg: a Tektronics 4014) then there
  157. X    may be a plot library available on your machine so you can use
  158. X    -l4014 and not have to type graph+ ... | plot ... all the time.
  159. X    On the Sun for example there is a tektronics emulator which I use
  160. X    for previewing graphs (they NEVER come out quite right the first time).
  161. X
  162. XAlan Kent,
  163. XDept Computer Science,
  164. XRoyal Melbourne Institute of Technology,
  165. XMelbourne, Australia.
  166. X
  167. XACSNet: ajk@goanna.oz
  168. XUUCP: {seismo,hplabs,mcvax,ukc,nttlab}!munnari!goanna.oz!ajk
  169. XARPA: munnari!goanna.oz!ajk@SEISMO.ARPA
  170. SHAR_EOF
  171. if test 6129 -ne "`wc -c < 'README'`"
  172. then
  173.     echo shar: error transmitting "'README'" '(should have been 6129 characters)'
  174. fi
  175. fi
  176. if test -f 'graph+.1'
  177. then
  178.     echo shar: will not over-write existing file "'graph+.1'"
  179. else
  180. echo extracting "'graph+.1'"
  181. sed 's/^X//' >graph+.1 <<'SHAR_EOF'
  182. X.\" Nroff -man
  183. X.de SY
  184. X.sp
  185. X.SH SYNTAX
  186. X.PP
  187. X.nf
  188. X..
  189. X.de ES
  190. X.SH EXAMPLES
  191. X.PP
  192. X.nf
  193. X..
  194. X.de EE
  195. X.fi
  196. X.SH DESCRIPTION
  197. X..
  198. X.TH graph+ ajk "31 January 1984"
  199. X.SH NAME
  200. Xgraph+ \- powerful graph generator program
  201. X.SH SYNOPSIS
  202. X.B graph+
  203. X[ commandfile | \- ]
  204. X[ parameter ... ]
  205. X.SH DESCRIPTION
  206. X.PP
  207. X.I Graph+
  208. Xis a utility program for producing graphs.
  209. XIts main advantage is that
  210. Xit allows easy manipulation of data using dynamic tables
  211. Xin memory using a relational style language (project etc.)
  212. Xrather than requiring a number of separate programs piped together.
  213. X.I Graph+
  214. Xalso allows functions to be defined returning values or tables.
  215. X.PP
  216. XBy placing the line
  217. X.PP
  218. X.in +4
  219. X #! /usr/rmit/graph+
  220. X.in -4
  221. X.PP
  222. Xat the beginning of a
  223. X.I graph+
  224. Xcommand file, the file can then be executed
  225. Xdirectly like a shell script, assuming that the binary file is in /usr/rmit.
  226. XOutput is in the format for input to the
  227. X.IR plot (1)
  228. Xfilters.
  229. X.PP
  230. XThe parameters can be referenced inside a plot program. The first parameter
  231. Xis given the number 1. This allows file names and graph titles to be
  232. Xpassed to a graph+ program. (See strings). If parameters are to be
  233. Xsuppied, but the actual program is on standard input, then \- must
  234. Xbe specified for the program file name. 'parms' is set to the number
  235. Xof parameters. Note that numeric parameters can be handled by using
  236. Xthe val() function.
  237. X.PP
  238. XIn
  239. X.IR graph+ ,
  240. Xa
  241. X.I table
  242. Xis a simple two dimensional array of floating point numbers.
  243. XTables can have any number of rows and columns.
  244. XData to be plotted is usually kept in files in a multicolumn format
  245. Xwith each line representing one piece of related data (say results
  246. Xfrom one experiment). An 
  247. X.I awk
  248. Xprogram can be used to extract data from a complexly structured data
  249. Xfile or from files containing text and reformat into columns of data
  250. Xif necessary.
  251. X.I Graph+
  252. Xdoes not allow text to
  253. Xbe read \- only floating point data.
  254. X.PP
  255. XAnywhere a
  256. X.I string
  257. Xcan appear, a string expression is allowed.
  258. XA string expression can consist of a list of concatenated strings
  259. Xsepearated by + symbols.
  260. XLiteral strings
  261. Xare enclosed in double quotes (").
  262. XTo embed a double quote in the string, place two double quotes
  263. Ximmediately adjacent to each other.
  264. XAlternatives for literal strings include the word
  265. X.I parameter
  266. Xfollowed by the parameter number (the first parameter is number 1).
  267. XThe reserved word
  268. X.I date
  269. Xreturns a string which consists of the
  270. Xcurrent time and date (UNIX format).
  271. XThe function
  272. X.I val(string)
  273. Xreturns the numeric value of a string.
  274. XThe function
  275. X.I str(expr)
  276. Xreturns a string containing the result of printf("%g",expr).
  277. XThe function
  278. X.I str(format,expr)
  279. Xallows your own printf format to be used.
  280. X.PP
  281. XA
  282. X.I graph+
  283. Xprogram consists of a number of statements.
  284. X.SH STATEMENTS
  285. X.PP
  286. XThe ';' is treated as a null statement. It can be used at between other
  287. Xstatements if desired. When graph+ is used interactively (ie. type
  288. Xgraph+ with no parameters) commands can be entered but due to the
  289. Xlook-ahead parser, the next statement must be entered before the
  290. Xexisting one is processed. Adding a ; to the end of the command
  291. Xthen causes the parser to realise that the end of a statement has
  292. Xbeen reached. Note also that due to problems with yacc(1), the
  293. Xinclude statement requires a ; after it (see below).
  294. X.SY
  295. Xassume <expr> <string>
  296. X.ES
  297. Xassume parms=3 "3 parameters expected: "+str(parms)+" parameters given"
  298. Xassume count(data) > 0 "data table empty"
  299. X.EE
  300. X.PP
  301. X.I Assume
  302. Xaborts a graph+ program if the expression evaluates to false.
  303. XThis allows simple checks for table sizes, numbers of parameters
  304. Xetc. to be inserted in a program and an error message to be
  305. Xprinted.
  306. X.SY
  307. X<tab_ident> = <table>
  308. X.ES
  309. Xdata = read "data.file"
  310. X.EE
  311. X.PP
  312. XDefines the identifier 
  313. X.I tab_ident
  314. Xto have the specified table of values.
  315. XTable identifiers may be referred to in
  316. X.I table
  317. Xexpressions. In the declaration,
  318. X.I tab_ident
  319. Xmust not have been already
  320. Xdefined unless it has already been defined as a table.
  321. X.SY
  322. X<var_ident> = <expr>
  323. X.ES
  324. Xpi = 3.1415
  325. X.EE
  326. X.PP
  327. XSimilar to a table declaration, except that the identifier has a single
  328. Xnumeric value assigned to it instead of a complete table.
  329. X.SY 
  330. X<ident> ( <dec_parm_list> ) = <expr>
  331. X<ident> ( <dec_parm_list> ) = <table>
  332. X.ES
  333. X# this function returns the ratio of two numbers
  334. X
  335. Xa = 0
  336. Xb = 0
  337. Xratio(a,b) = a/b
  338. X
  339. X# this function limit returns a table of values where column
  340. X# 1 is less than the specified limit
  341. X
  342. Xlimit_val = 0     # declare parameters
  343. Xlimit_tab = {{0}}  # declares a table
  344. Xlimit ( limit_tab , limit_val ) = limit_tab where $1 < limit_val
  345. X.EE
  346. X.PP
  347. XDeclares a function which returns 
  348. Xa simple value or a table of values.
  349. XFunction identifiers can never be redefined.
  350. XThe parameter lists consist of a comma separated list of
  351. X.I tab_ident
  352. Xor
  353. X.I var_ident
  354. Xidentifers
  355. X.B "which must have been previously defined"
  356. X(see above example).
  357. XThese identifiers will act as parameters to the functions in the following
  358. Xway. When the function is called, the identifiers are redeclared with
  359. Xthe parameter values. Care must be taken for nested function calls as if they
  360. Xuse the same identifier names for parameters, the parameters to function
  361. XA might be changed after returning from a call to function B.
  362. XIt is common to declare special variables for parameters to functions
  363. Ximmediately before the actual function to be certain of the parameter type.
  364. X.SY
  365. Xinclude <string> ;
  366. X.ES
  367. Xinclude "bar_chart.g" ;
  368. X.EE
  369. X.PP
  370. XThe
  371. X.I include
  372. Xstatement allows another file of
  373. X.I graph+
  374. Xcommands to be included. This is useful for including function declarations.
  375. XThe ; is needed only because of the current implementation of the parser.
  376. XWhen an include is done, one token after the string is accidently lost.
  377. XThis may not be consistant across implementations of yacc and lex.
  378. X.SY
  379. Xshell <string>
  380. X.ES
  381. Xshell "awk -f complex.awk prelimfile > finalfile"
  382. Xdata = read "finalfile"
  383. X.EE
  384. X.PP
  385. XThe
  386. X.I shell
  387. Xcommand allows a command to be passed to the shell 'sh'.
  388. XThis can be used
  389. Xto generate a file to be read by including an output redirection.
  390. X.SY
  391. Xprint <table>|<expr>|<string>
  392. Xprint > <string> <table>|<expr>|<string>
  393. Xprint >> <string> <table>|<expr>|<string>
  394. X.ES
  395. Xprint "saving data to file copy.of.data"  # print message on screen
  396. Xprint > "copy.of.data" data  # save data on a file
  397. Xprint >> "copy.of.data" more_data  # append some more data
  398. X.EE
  399. X.PP
  400. XThe
  401. X.I print
  402. Xcommand can have its output redirected (overwrite or append) to a
  403. Xfile called
  404. X.I <string>
  405. Xand print out a table, the result of an expression or a simple string.
  406. XIf two prints to the same file are used, make sure the second is and
  407. Xappend redirect (>>).
  408. X.SY
  409. Xsave <table> as <string>
  410. X.ES
  411. Xdata = read "text.data"
  412. Xsave data as "data.binary"
  413. Xprint > "text.data" load "data.binary"  # converts a binary file back to text
  414. X.EE
  415. X.PP
  416. XThe
  417. X.I save
  418. Xcommand saves the table of data in binary format for faster loading
  419. Xwith the
  420. X.I load
  421. Xcommand. This is useful when a large datafile is to be read a number
  422. Xof times by different plot programs as the binary file can be loaded
  423. Xmuch more quickly than textual versions. It is also possible that
  424. Xthe binary file will require less disk space. The format of the
  425. Xbinary file is simply two integers (number of columns and number
  426. Xof rows) followed by all the data (doubles).
  427. XThe data is written out column by column so the first double is
  428. Xthe first value in the first column, the second value is the
  429. Xsecond value in the first column and so on.
  430. XBinary files may not be transportable across machines.
  431. X.SY
  432. Xgraph <table> [ <option> ... ]
  433. X<option> = no|solid|dotted|shortdashed|longdashed|dotdashed line
  434. X<option> = no|triangle|circle|square|cross|plus points
  435. X<option> = label <string>
  436. X<option> = legend <string>
  437. X.ES
  438. Xgraph data
  439. Xgraph data2 dotted line
  440. Xgraph data3 dotdashed line label "data3"
  441. Xgraph data no line cross points circle points # put a circle and cross
  442. Xgraph {{10,20}} label "text at 10,20"
  443. X.EE
  444. X.PP
  445. XThe
  446. X.I graph table
  447. Xcommand specifies details of an actual graph to plot. The table specified
  448. Xmust have exactly two columns, the first column being for x coordinatates and
  449. Xthe second for y coordinates. Multiple
  450. X.I graph
  451. Xcommands will cause multiple graphs to be drawn on the same axis.
  452. X.PP
  453. XThe graph options allow the type of line to draw the graph to
  454. Xbe specified (default is solid) and for a label to be printed on the
  455. Xfinal graph after the last point of the data. Note that text can be
  456. Xpositioned anywhere on a graph by using a constant table and a label
  457. X(as in the example above).
  458. X.PP
  459. XThe
  460. X.I legend
  461. Xoption can be used instead of the label option if a separate legend
  462. Xis wanted. The label option often fails when more than one graph end
  463. Xat the same point causing the labels to be overwritten making them
  464. Xunreadable. The
  465. X.I put
  466. X.I legend
  467. X.I at
  468. Xstatement can be used to position the legend on the graph (the legend
  469. Xcannot be put below the graph).
  470. X.PP
  471. XThe point information (circle, triangle etc) is drawn per point in the
  472. Xgraph. The
  473. X.I "no line"
  474. Xoption must be used if only the points are to be
  475. Xmarked. The default points value is 
  476. X.I "no points."
  477. XNote that multiple
  478. Xpoints options on the same graph statement will cause the different
  479. Xtypes of points to be superimposed. This means a crossed circle can
  480. Xbe done using 
  481. X.I "crossed points circle points."
  482. XNote that only one line type can be specified however.
  483. X.SY
  484. Xgraph label <string>
  485. X.ES
  486. Xgraph label "Statistics for the year 1986  " + date
  487. X.EE
  488. X.PP
  489. XAllows a label to be placed at the top of the graph.
  490. XIf this command is not specified, no label
  491. Xis printed. Note that the string (as like all other strings)
  492. Xcan be a concatenation of literal strings and other
  493. Xbuilt in operators (like
  494. X.IR date ).
  495. X.SY
  496. Xxaxis [ <axis_option> ... ]
  497. Xyaxis [ <axis_option> ... ]
  498. X<axis_option> can be one of
  499. X    label <string>    (default none)
  500. X    format <string>    (default depends on range of data)
  501. X    auto|no scale    (default auto scale)
  502. X    frame|grid|outline|no axis    (default grid axis)
  503. X    logarithmic|linear    (default linear)
  504. X    from <expr> to <expr>
  505. X    tick size <expr> [ power <expr> ]
  506. X.ES
  507. X# xaxis will have all values marked and vertical lines drawn over the
  508. X# whole graph per tick value
  509. Xxaxis label "Year" format "%4f"
  510. X    from 1980 to 1986 tick size 1
  511. X# yaxis will have only the tick values drawn (no horizontal lines)
  512. X# The data will be made logarthmic and the label will be spilt over
  513. X# two lines: "Population" and "per year"
  514. Xyaxis frame axis logarithmic label "Population per~year"
  515. X
  516. X# another example with ticks
  517. Xyaxis tick size 2 power 3  # ticks are really of size 2000 (2 x 10^3)
  518. X.EE
  519. X.PP
  520. XThe
  521. X.I xaxis
  522. Xand
  523. X.I yaxis
  524. Xstatements allow details to be specified on how the x and y axis lines
  525. Xfor the graph frame should be drawn.
  526. X.PP
  527. XThe
  528. X.I label
  529. Xoption is used to define what label to place on the axis.
  530. XOn the Y axis, the words (separated by blanks) are placed on separate lines
  531. Xone above the other. To place two words on the same line
  532. X(for example if there are two short words) use a '~' instead
  533. Xof a space. When the label is printed, the '~' will be changed
  534. Xinto a blank.
  535. XThe best way to write the label would be by rotating the text
  536. Xby 90 degrees, but the plot(1) format does not allow this.
  537. X.PP
  538. XThe
  539. X.I format
  540. Xoption allows a printf format string for a long floating point number
  541. X('double' in the 'C' programming language)
  542. Xfor printing the numbers on the ticks along the axis. No checking of
  543. Xthis format string is made. The default format is generally acceptable.
  544. X.PP
  545. XThe
  546. X.I scale
  547. Xoption allows the values along the axis to be automatically scaled by
  548. Xlabeling the axis as 'x 10^n' where n is the power. For example,
  549. Xfor values from 0 to 10000 may be shown on the ticks as from 0 to 10.0
  550. Xwith a factor of 10^3. The default is to
  551. X.I auto
  552. X.I scale
  553. Xbut the
  554. X.I no
  555. X.I scale
  556. Xoption can inhibit this.
  557. X.PP
  558. XThe
  559. X.I axis
  560. Xoption allows different forms of axis lines to be drawn.
  561. XNormally both axis will be given the same axis type, but this
  562. Xis not necessary.
  563. XThe
  564. X.I frame
  565. Xoption simply draws a single line along which ticks are place with
  566. Xnumeric values.
  567. XThe
  568. X.I grid
  569. Xoption draws a grid over the whole graph.
  570. XThe
  571. X.I outline
  572. Xoption is very similar to the 
  573. X.I frame
  574. Xoption but a second line is drawn on the far side of the graph.
  575. XIf this option is used on both axis or with a grid on the other axis,
  576. Xthe graph will appear to be enclosed in a box.
  577. XIf no axis (and no numbering) is desired, use the
  578. X.I no
  579. Xoption.
  580. XThe best way to find out what these do exactly is to experiment.
  581. X.PP
  582. XThe
  583. X.I linear
  584. Xand
  585. X.I logarithmic
  586. Xoptions allow a simple linear (default) or logarithmic graph to be
  587. Xplotted.
  588. X.PP
  589. XThe
  590. X.I from
  591. Xclause allows the range of values for the axis to be specified.
  592. XBy default this is calculated from the graphs to be plotted by
  593. Xdetermining the minimum and maximum values.
  594. X.PP
  595. XThe
  596. X.I tick
  597. X.I size
  598. Xclause allows the tick sizes to be specified. Normally this option would
  599. Xnot be used as graph+ tries to automatically calculate a nice looking
  600. Xvalue for the tick size and power (based on how much will fit on the output).
  601. XFractions for tick sizes (eg 1.33333) do not work well and due to rounding
  602. Xproblems may cause tick marks to be skipped along the axis. Round numbers
  603. Xshould be safe.
  604. XIf
  605. X.I power
  606. Xis not specified, then it is defaulted to 0. If a value of say 3 is used,
  607. Xthen the tick values will really be the tick size specified by 10^3 and
  608. Xthe power will be printed below the axis label in the form 'x 10^3'.
  609. X.SY
  610. Xput legend at top|middle|bottom left|center|right
  611. X.ES
  612. Xgraph data1 dotted line legend "graph 1"
  613. Xgraph data2 solid line legend "graph 2"
  614. Xput legend at bottom left
  615. Xplot
  616. X.EE
  617. X.PP
  618. XThe
  619. X.I put
  620. X.I legend
  621. X.I at
  622. Xstatement is used to position the legend on the graph. The legend
  623. X(at present) is drawn on top of the actual graph (underneath may
  624. Xbe better, but is harder due to the way the plot(1) functions work).
  625. XThe top/middle/bottom option selects the verical positioning and
  626. Xthe left/center/right option selects the horizontal positioning.
  627. XThe default position is the top right corner of the graph.
  628. X.SY
  629. Xplot
  630. X.ES
  631. Xgraph data1 solid line
  632. Xgraph data2 dotted line
  633. Xplot
  634. Xgraph data3 dotted line
  635. X.EE
  636. X.PP
  637. XThe
  638. X.I plot
  639. Xcommand generates a plot of all the graph statements done so far.
  640. XAny following graph commands will appear on the next plot.
  641. XA plot command is automatically performed at the very end of
  642. Xa command file if any graph statements have been found.
  643. X.SH TABLES
  644. X.PP
  645. XA <table> can be an expression made up from any of the following
  646. Xsub-expressions. These usually appear directly in
  647. X.I graph
  648. Xstatements, or when assigned to a table variable.
  649. X.SY
  650. Xread <file_name_string>
  651. Xread <cols_expr> by <rows_expr> <file_name_string>
  652. X.ES
  653. Xdata = read "data.file"
  654. Xgraph read 2 by 200 "data.file" # I know the file is 2 colums by 200 lines
  655. Xdata = read parameter 2 + ".dat"
  656. X.EE
  657. X.PP
  658. XThe
  659. X.I read
  660. Xcommand reads a table from a file. Blank lines
  661. Xand all characters from # to the end of line are ignore (allowing
  662. Xcomments to be put in data files). The number
  663. Xof columns in the table is determined by reading the first non-blank
  664. Xline in the file. The number of rows is determined by counting
  665. Xthe number of non-blank lines in the file. To read a file, two passes
  666. Xare made \- the first to determine the table size so a table can be
  667. Xallocated enough memory, and a second to read the actual values.
  668. X.PP
  669. XThe second form of the
  670. X.I read
  671. Xcommand allows the dimensions of the table to be prespecified so that
  672. Xonly one pass of the file is needed. This makes the command slightly
  673. Xfaster but much less flexible to changes in the data file. The first
  674. X.I expr
  675. Xspecifies the number of columns (which must be correct)
  676. Xand the second specifies the number of rows (which can be too large \-
  677. Xthe table is simply truncated although enough memory is allocated for
  678. Xthe full table.
  679. X.PP
  680. XThe ability to create strings from concatenations of sub-strings
  681. Xis very useful when specifying a filename. In particular, the
  682. Xability to extract parameters to the command allows the same
  683. Xplot program to be used with several data files.
  684. X.SY
  685. Xload <string>
  686. X.ES
  687. Xdata = load "data.file"
  688. X.EE
  689. X.PP
  690. X.I load
  691. Xis very similar to
  692. X.I read
  693. Xexcept that it loads a binary file saved with the
  694. X.I save
  695. Xcommand. The binary file format is described under the
  696. X.I save
  697. Xcommand.
  698. X.SY
  699. X{ { <expr> , <expr> , ... } { <expr> , <expr> , ... } ... }
  700. X.ES
  701. Xconst_table = { {0,0} {1,2} {3,10} {4,20} } # 2 cols, 4 rows
  702. Xcalc_table = { {0,log(0)} {10,log(10)} {100,log(100)} }
  703. Xgraph {{10,20}} label "label at 10,20 on graph"
  704. X.EE
  705. X.PP
  706. XBraces allow a table of expressions to be specified.
  707. XOne set of braces surround
  708. Xthe whole table, each row in the table being specified by a comma
  709. Xseparated list of expressions surrounded in one set of braces per row.
  710. X.SY
  711. Xgenerate from <expr> to <expr> <interval>
  712. X<interval> = with <expr> intervals
  713. X<interval> = interval size <expr>
  714. X.ES
  715. Xtab_size = 10
  716. Xlog_table = generate from 1 to tab_size interval size 1 [ $1 , log($1) ]
  717. Xsingle_col_table = generate from 1 to 100 with 11 intervals
  718. X.EE
  719. X.PP
  720. XThe
  721. X.I generate
  722. Xcommand generates a single column table of values in the specified from\-to
  723. Xrange using the specified interval details.
  724. X.SY
  725. X<table> append <table>
  726. X.ES
  727. Xtotal_dat = dat1 append dat2
  728. X.EE
  729. X.PP
  730. XThe
  731. X.I append
  732. Xcommand appends the second
  733. X.I table
  734. Xto the end of the first
  735. X.I table.
  736. XBoth tables must have the same number of columns.
  737. X.SY
  738. X<table> adjacent <table>
  739. X.ES
  740. Xwide_tale = dat1 adjacent dat2
  741. X.EE
  742. X.PP
  743. XThe
  744. X.I adjacent
  745. Xcommand is similar to the
  746. X.I append
  747. Xcommand, but it joins tables horizontally instead of vertically.
  748. XBoth tables can have different numbers of columns, but must have the
  749. Xsame number of rows.
  750. X.SY
  751. X<table> [ <expr> , <expr> , ... ]
  752. X.ES
  753. Xgraph all_data [ $1 , $3 ] # plot columns 1 vs 3
  754. Xgraph all_data [ $0 , ($1+$3)/2 ] # plot the average of column 1 and 3
  755. X.EE
  756. X.PP
  757. XThe projection command (square brackets) allows data to be extracted
  758. Xfrom a table, or new columns of data to be formed from expressions based
  759. Xon existing columns of data. See the
  760. X.I expr
  761. Xfor exact details of how to extract columns of data from a table.
  762. XThe number of rows in the new table is the same as the number of
  763. Xrows in the old table, but the number of columns is dependent on the
  764. Xnumber of expressions in the comma separated list of expressions inside
  765. Xthe square brackets.
  766. X.SY
  767. X<table> where <expr>
  768. X.ES
  769. Xsome_data = data where $0 <= 100   # select first 100 entries in table
  770. Xsome_data = data where $1 >= $2/2   # select lines where first column is
  771. X   # greather than or equal to half the second column
  772. X.EE
  773. X.PP
  774. XThe
  775. X.I where
  776. X(or selection) command forms a new table with the same number of columns
  777. Xas the old table, but only containing rows that satisfy the condition
  778. X.I expr.
  779. XThe expression normally uses relational operators such as <, >= etc.
  780. Xbut any expression can be used. A return value of 0.0 is considered as
  781. Xfalse, any other value being true (as in the 'C' programming language).
  782. X.SY
  783. Xsort <table> by <attr>
  784. X.ES
  785. Xdata = sort data by $2
  786. X
  787. X# sort table of two columns by the sum of the two columns
  788. Xsorted_data = sort ( data [ $1 , $2 , $1+$2 ] ) by $3 [ $1 , $2 ]
  789. X.EE
  790. X.PP
  791. XThe
  792. X.I sort
  793. Xcommand allows a table to be sorted by a column in the table specified by
  794. X.I attr.
  795. XThe column specified cannot be column zero (which has a special use).
  796. XAn
  797. X.I attr
  798. Xwas used to sort on instead of any expression for efficency reasons.
  799. XTo sort by an expression, simply project an extra column into the table
  800. Xbefore sorting, and remove it (with another project) later.
  801. XThe sort algorithm used is a version of quicksort.
  802. X.SY
  803. Xjoin <table1> , <table2> by <attr1> , <attr2>
  804. X.ES
  805. Xdata = join dat1 , dat2 by $1 , $1
  806. X.EE
  807. X.PP
  808. XThe
  809. X.I join
  810. Xcommand performs an equi-join on the two tables of data.
  811. X<attr1> and <attr2> specify the fields on which the join is
  812. Xto be performed. If the data in the two tables is not found
  813. Xto be sorted on the join fields, the tables are sorted automatically.
  814. XThe join then creates a new table which contains all the columns
  815. Xof <table1> followed by all the columns of <table2> (the join
  816. Xfield is NOT removed and so will appear in the resultant table twice).
  817. X.SY
  818. Xcumulate <table> by <attr>
  819. X.ES
  820. Xgraph cumulate cost_per_unit by $2
  821. X.EE
  822. X.PP
  823. XThe
  824. X.I cumulate
  825. Xcommand takes a column in a table specified by
  826. X.I attr
  827. Xand replaces each entry with the sum of the present value and all the
  828. Xprevious values. This is useful for plotting cumulative graphs.
  829. X.SY
  830. Xgroup <table> [ from <expr> to <expr> ] <interval> performing <function>
  831. X.ES
  832. Xgraph group sort data by $1 with 10 intervals performing max [ ($1+$2)/2 , $3 ]
  833. Xdata = group data from 10 to 20 with interval size 5 performing average
  834. X.EE
  835. X.PP
  836. XThe
  837. X.I group
  838. Xcommand is fairly complex but allows graphs to be split into a number
  839. Xof intervals with the specified function
  840. X.RI ( fvar_ident )
  841. Xbeing called for each interval.
  842. XThe function must return a simple value and have a single parameter of
  843. Xa table (such as the predefined 
  844. X.IR sum ,
  845. X.IR min ,
  846. X.IR max ,
  847. X.I count
  848. Xand
  849. X.I average
  850. Xfunctions.
  851. X.PP
  852. XThe group table must have exactly two colums, the first column
  853. Xbeing used for grouping by and the second containing the values to pass
  854. Xto the function. The table must have already been sorted on the first column.
  855. XProjects are often made to tables to get them into the
  856. Xcorrect form for a grouping.
  857. XThe optional range specification (if no range is specified, the minimum and
  858. Xmaximum values are calculated from the table) defines the upper and lower
  859. Xbound of values to be considered in the group.
  860. XThe interval specification is used to determine the number of and size of
  861. Xthe group intervals. Beware of intervals have no values in them. These
  862. Xwill cause the function to be called with an empty table.
  863. X.PP
  864. XThe result of a group has extactly three columns. The first two columns
  865. Xcontain the lower and upper bound values of the interval and the third
  866. Xcolumn contains the result of the function when applied to all of the
  867. Xvalues within that interval. From this, it is fairly simple to produce
  868. Xdifferent forms of graphs (eg bar graphs, line graphs).
  869. X.SY
  870. X<function_ident> ( <expr> , <expr> , ... )
  871. X.ES
  872. Xprint min ( data_table )
  873. Xprint average ( data_table[$3] )
  874. X
  875. Xtab = {{0}}
  876. Xftab(tab) = count ( tab[$1] ) / average ( tab[$2] )
  877. Xprint ftab({{1,1}{4,4}})
  878. X.EE
  879. X.PP
  880. X.I <function_ident>
  881. Xis a table function name which is called with the specified parameter list.
  882. X.PP
  883. XTable identifiers return the value of the table as last declared
  884. Xwith "=" or when declared as a parameter.
  885. X.SY
  886. X( <table> )
  887. X.ES
  888. Xsort ( data[ $1 , $3 ] ) by $2
  889. X.EE
  890. X.PP
  891. XSimple parenthisis allow the priority of evaluation to be forced.
  892. XDefault priority of table operators listed from highest priority to lowest is
  893. Xselect and project, adjacent, append, sort, group and cumulate.
  894. X.SH EXPRESSIONS
  895. X.PP
  896. XIn the following, a true value is considered to be any non-zero value,
  897. Xand false is considered to be the value 0.
  898. XThe operators are listed here from lowest to highest priority.
  899. X.SY
  900. X<expr> "?" <expr> ":" <expr>
  901. X.ES
  902. Xdata = data [ $1 , $2<=0 ? 0 : log($2) ]
  903. X.EE
  904. X.PP
  905. XThe
  906. X.I '?'
  907. Xoperator returns the value of the second
  908. Xexpression if the first expression is true; otherwise the value of the third
  909. Xexpression is returned.
  910. X.SY
  911. X<expr> || <expr>
  912. X.ES
  913. Xdata = data where $1<10 || $1>20
  914. X.EE
  915. X.PP
  916. XThe logical OR operator ('||') returns true if either expression returns
  917. Xtrue, false otherwise.
  918. X.SY
  919. X<expr> && <expr>
  920. X.ES
  921. Xdata = dat where $1>10 && $2<20
  922. X.EE
  923. X.PP
  924. XThe logical AND operator ('&&') returns true if both expressions return true,
  925. Xfalse otherwise.
  926. X.SY
  927. X<expr> =|==|<>|!=|<=|<|>|>= <expr>
  928. X.ES
  929. Xdata = data where $1>10 | $2 = 0
  930. X.EE
  931. X.PP
  932. XThese relational operators return true or false based on the operator
  933. Xand the results of the two expressions. Note that equivalence can be
  934. Xspecified with either '=' or '==' and inequivalence can be specified
  935. Xwith either '<>' or '!='.
  936. X.SY
  937. X<expr> +|\- <expr>
  938. X.ES
  939. Xprint data[ $1+$2 , $1\-$2 ]
  940. X.EE
  941. X.PP
  942. XThese are the simple arithmetic addition and subtraction operators.
  943. X.SY
  944. X<expr> /|*|% <expr>
  945. X.ES
  946. Xpi = 3.1415
  947. Xprint pi / 3
  948. Xprint pi * 3
  949. Xprint 100 % 3
  950. X.EE
  951. X.PP
  952. XDivide, multiply and modulus operators.
  953. X.SY
  954. X<primary> =
  955. X    \- <primary>
  956. X    ! <primary>
  957. X    ( <expr> )
  958. X    <attr>
  959. X    <number>
  960. X    <func_var_ident> ( <expr>|<table> , <expr>|<table> , ... )
  961. X    <var_ident>
  962. X    parms
  963. X.ES
  964. Xprint -3
  965. Xprint !3
  966. Xprint data[ $2 ]
  967. Xpi = 3.1415
  968. Xprint pi
  969. Xtab={{0}}
  970. Xsizeof ( tab ) = count ( tab )
  971. Xprint "table size should be 2"
  972. Xprint sizeof ( {{1},{2}} )
  973. X.EE
  974. X.PP
  975. X.I Primary
  976. Xexpressions are separated in the syntax as an attribute specification
  977. X(see 
  978. X.IR attr )
  979. Xcan only be a
  980. X.I primary
  981. Xexpression, typically a simple number.
  982. X.PP
  983. XThe minus unary operator is for negation.
  984. X.PP
  985. XThe NOT ("!") operator returns the oposite boolean value of the expression.
  986. X.PP
  987. XParenthises allow the default operator precidence to be overridden.
  988. X.PP
  989. X.I Numbers
  990. Xare any floating point number.
  991. X.PP
  992. X.IR <fvar_ident> s
  993. Xare variable function names, the parameters being listed inside
  994. Xthe parenthises.
  995. X.PP
  996. X.IR <var_ident> s
  997. Xare variables defined with the "=" operator or by parameter passing.
  998. X.PP
  999. X.I parms
  1000. Xreturns the number of command line parameters given to the program.
  1001. XThis is really only of any use in an
  1002. X.I assume
  1003. Xstatement (assume parms = 3 "3 parameters expected").
  1004. X.SY
  1005. X<attr> = $ <primary>
  1006. X.ES
  1007. Xgraph data[ $1 , $2 ]
  1008. Xsumcol = 3
  1009. Xgraph data[ $1 , $sumcol ]
  1010. Xgraph data[ $1 , $($1<100 ? 2 : 3 ) ]  # choose column based on $1
  1011. Xprint > "savefile" data[ $0 , $1 , $2 ]
  1012. X.EE
  1013. X.PP
  1014. X.IR <attr> 's
  1015. Xspecify which column of a table to use.
  1016. XColumn numbers start from 1 and count upwards.
  1017. XIn an expression, the value
  1018. Xof that column is returned if used in a project or select type command
  1019. Xfor which the expression is re-evaluated for every row of a table.
  1020. XIn expressions, column zero may be specified which returns the row number
  1021. X(starting from 1)
  1022. Xof the row instead of data from the table.
  1023. X.SH "PREDEFINED FUNCTIONS"
  1024. X.PP
  1025. XThere are a number of predefined funtions, all of which at present return
  1026. Xvalues.
  1027. X.TP
  1028. X.BI str (expr)
  1029. X.TP
  1030. X.BI str (format,expr)
  1031. XReturn a string containing the value of the given expression.
  1032. XIf no format is specified, "%g" is used. The format is passed straight
  1033. Xto sprintf().
  1034. X.TP
  1035. X.BI min (table)
  1036. XReturn the minimum value in the first column of
  1037. X.IR table .
  1038. XIf the table is empty, a warning is printed on stderr and a value of 0.0 is
  1039. Xreturned.
  1040. X.TP
  1041. X.BI max (table)
  1042. XReturn the maximum value in the first column of
  1043. X.IR table .
  1044. XIf the table is empty, a warning is printed on stderr and a value of 0.0 is
  1045. Xreturned.
  1046. X.TP
  1047. X.BI sum (table)
  1048. XReturn the total of all the values in the first column of
  1049. X.IR table .
  1050. XIf the table is empty, a warning is printed on stderr and a value of 0.0 is
  1051. Xreturned.
  1052. X.TP
  1053. X.BI count (table)
  1054. XReturn the number of rows in
  1055. X.IR table .
  1056. X.TP
  1057. X.BI average (table)
  1058. XReturn the average value in the first column of
  1059. X.IR table .
  1060. XIf the table is empty, a warning is printed on stderr and a value of 0.0 is
  1061. Xreturned. This is like doing a
  1062. X.I sum
  1063. Xdivided by a
  1064. X.I count.
  1065. X.PP
  1066. XThe following mathmatical functions are straight from the math library
  1067. Xand suffer from all their constraints (no checking is done). See section
  1068. X3(M) in the Unix Programmers Manual.
  1069. X.TP
  1070. X.BI sqrt (expr)
  1071. XReturn the square root of the given expression.
  1072. X.TP
  1073. X.BI log (expr)
  1074. XReturn log10 of the given expression.
  1075. X.TP
  1076. X.BI ln (expr)
  1077. XReturn the natural log of the given expression.
  1078. X.TP
  1079. X.BI exp (expr)
  1080. XReturn e to the power of expr.
  1081. X.TP
  1082. X.BI pow (expr1,expr2)
  1083. XReturn 
  1084. X.I expr1
  1085. Xto the power of
  1086. X.I expr2.
  1087. X.TP
  1088. X.BI floor (expr)
  1089. XReturn the largest integer not greater than
  1090. X.I expr.
  1091. X.TP
  1092. X.BI ceil (expr)
  1093. XReturn the smallest integer not less than
  1094. X.I expr.
  1095. X.TP
  1096. X.BI abs (expr)
  1097. XReturn the absolute value of
  1098. X.I expr.
  1099. X.TP
  1100. X.BI sin (expr)
  1101. XReturn sine of
  1102. X.I expr.
  1103. X.TP
  1104. X.BI cos (expr)
  1105. XReturn cosine of
  1106. X.I expr.
  1107. X.TP
  1108. X.BI asin (expr)
  1109. XReturn arc-sine of
  1110. X.I expr
  1111. Xin the range from -pi/2 to +pi/2.
  1112. X.TP
  1113. X.BI acos (expr)
  1114. XReturn arc-cos of
  1115. X.I expr
  1116. Xin the range 0 to pi.
  1117. X.TP
  1118. X.BI atan (expr)
  1119. XReturn arc-tangent of
  1120. X.I expr
  1121. Xin the range -pi/2 to +pi/2.
  1122. X.TP
  1123. X.BI atan2 (expr1,expr2)
  1124. XReturn arc-tangent of
  1125. X.I expr1/expr2
  1126. Xin the range -pi to +pi.
  1127. X.TP
  1128. X.BI sinh (expr)
  1129. XReturn hyperbolic sine of
  1130. X.I expr.
  1131. X.TP
  1132. X.BI cosh (expr)
  1133. XReturn hyperbolic cosine of
  1134. X.I expr.
  1135. X.TP
  1136. X.BI tanh (expr)
  1137. XReturn hyperbolic tangent of
  1138. X.I expr.
  1139. X.TP
  1140. X.BI hypot (expr1,expr2)
  1141. XReturns the square root of the sum of the squares of
  1142. X.I expr1
  1143. Xand
  1144. X.I expr2.
  1145. X.TP
  1146. X.BI j0 (expr)
  1147. X.TP
  1148. X.BI j1 (expr)
  1149. X.TP
  1150. X.BI jn (expr1,expr2)
  1151. X.TP
  1152. X.BI y0 (expr)
  1153. X.TP
  1154. X.BI y1 (expr)
  1155. X.TP
  1156. X.BI yn (expr1,expr2)
  1157. XBessel functions.
  1158. X.TP
  1159. X.BI val (string)
  1160. XReturn the numeric value of the specified string.
  1161. XThis is particularly useful for getting numeric parameters from the
  1162. Xcommand line.
  1163. X.SH EXAMPLE
  1164. X.PP
  1165. XThe following are some simple examples to try and help show how to actually
  1166. Xuse all these commands.
  1167. X.PP
  1168. X #! /usr/rmit/graph+
  1169. X  
  1170. X # some constant tables
  1171. X  
  1172. X file1={ { 0, 1 } { 1, 20 } { 2, 30 } { 3, 16 } { 4, 19 } { 5, 29 } }
  1173. X file2={ { 0, 3 } { 1, 15 } { 2, 34 } { 3, 12 } { 4, 12 } { 5, 24 } }
  1174. X
  1175. X num = 6
  1176. X  
  1177. X final = sort (file1 append file2 )  by $1
  1178. X  
  1179. X # the output of graph can not be directly printed.
  1180. X # turn a graph table into a list of lines through
  1181. X # the middle of each interval by forming a table
  1182. X # with the first column being the middle of the group
  1183. X # interval (the average of the first two columns) and
  1184. X # the other column being the actual data
  1185. X  
  1186. X lineg_tab={{0}} # dummy declaration for function parameter
  1187. X lineg(lineg_tab) = lineg_tab[ ($1+$2)/2 , $3 ]
  1188. X  
  1189. X graph lineg( group final with num intervals performing max )
  1190. X graph lineg( group final with 10 intervals performing min )
  1191. X graph file1 label "file"
  1192. X graph cumulate(file1) label "cumulative"
  1193. X  
  1194. X xaxis label "This is the x-axis"
  1195. X yaxis label "This is~the y-axis"
  1196. X # will appear
  1197. X #   This
  1198. X #  is the
  1199. X #  y-axis
  1200. X.PP
  1201. XA more typical example is
  1202. X.PP
  1203. X data1 = read "results.1"
  1204. X data2 = read "results.2"
  1205. X graph data1[ $1 , $2 ] dotted line label "first results"
  1206. X graph data2[ $1 , $2 ] shortdashed line label "second results"
  1207. X graph ( data1[$1,$2] adjacent data2[$2] ) [ $1 , ($2+$3)/2 ]
  1208. X    solid line label "average"
  1209. X.SH DIAGNOSTICS
  1210. X.PP
  1211. XError recovery is poor. Syntax error can mean almost anything, the
  1212. Xparse being a simple yacc program. Note that undefined identifiers
  1213. X(due to typing errors) can also come up as syntax errors.
  1214. X.SH BUGS
  1215. X.PP
  1216. XAlmost infinite. But the program in general does work. Its just that
  1217. XI personally find the graphs are often not quite what I want.
  1218. XIt is however MUCH better than the standard unix graph(1) command
  1219. Xand allows good manipulation of data much faster than awk(1).
  1220. X.PP
  1221. XOne problem that can occur is running out of memory.
  1222. XAll tables are held in memory - never on disk.
  1223. XThe program works be continually building new tables from
  1224. Xthe contents of old tables and then (if possible) freeing the
  1225. Xold tables. Parameters after being called do not free the space
  1226. Xconsumed by the parameter declaration, so large data files can
  1227. Xcause a lot of memory to be held by the graph+ program.
  1228. X.PP
  1229. XThere would need to be several thousand more options to be able to
  1230. Xprint all forms of graphs to keep everyone happy.
  1231. X.PP
  1232. XIf you have any problems, do not mail to ajk@goanna.oz ;-)
  1233. X.SH AUTHOR
  1234. XAlan Kent (ajk@goanna.oz)
  1235. X.SH SEE ALSO
  1236. Xleplot(ajk), awk(1), graph(1), plot(1), plot(3x).
  1237. SHAR_EOF
  1238. if test 30797 -ne "`wc -c < 'graph+.1'`"
  1239. then
  1240.     echo shar: error transmitting "'graph+.1'" '(should have been 30797 characters)'
  1241. fi
  1242. fi
  1243. if test -f 'Makefile'
  1244. then
  1245.     echo shar: will not over-write existing file "'Makefile'"
  1246. else
  1247. echo extracting "'Makefile'"
  1248. sed 's/^X//' >Makefile <<'SHAR_EOF'
  1249. X
  1250. XCFLAGS= -O -DGLOB_LIB=\"/r/pmr/ajk/lib/graph+rc\"
  1251. X#CFLAGS=    -O -DGLOB_LIB=\"/r/pmr/ajk/lib/graph+rc\" -DLASER
  1252. X
  1253. XLIBS=    -lm -ll -lplot
  1254. X#LIBS=    -lm -ll -l4014
  1255. X
  1256. XYFLAGS=    -d
  1257. XPROG=    graph+
  1258. XOBJS=    yacc.o lex.o \
  1259. X    abort.o adjacent.o appendtb.o attrnode.o average.o count.o \
  1260. X    cpyentry.o cpytable.o cumulate.o dumpgrph.o eval.o evaltab.o \
  1261. X    freetab.o fundeclr.o generate.o global.o group.o include.o \
  1262. X    join.o main.o max.o min.o new.o newtable.o numcols.o parmnode.o \
  1263. X    printtab.o project.o readtab.o reset.o saveload.o select.o sort.o \
  1264. X    sum.o tabdeclr.o tabnode.o vardeclr.o
  1265. X
  1266. XAll : $(PROG)
  1267. X
  1268. X$(PROG) : $(OBJS)
  1269. X    cc -o $(PROG) $(OBJS) $(LIBS)
  1270. X
  1271. Xshar :
  1272. X    shar README graph+.1 Makefile bar_graph best_fit graph.h yacc.y > g1.shar
  1273. X    shar [a-f]*.c > g2.shar
  1274. X    shar [g-z]*.c lex.l > g3.shar
  1275. X
  1276. Xclean :
  1277. X    /bin/rm $(OBJS)
  1278. X
  1279. Xlink :
  1280. X    cc -pg -o $(PROG) $(OBJS) $(LIBS)
  1281. X
  1282. X# following line needed if numbering of tokens change
  1283. X# but otherwise just causes lots more compiles.
  1284. X
  1285. Xcumulate.o lex.o fundeclr.o dumpgrph.o eval.o evaltab.o \
  1286. Xreset.o group.o main.o parmnode.o: y.tab.h 
  1287. X
  1288. X$(OBJS): graph.h
  1289. SHAR_EOF
  1290. if test 1060 -ne "`wc -c < 'Makefile'`"
  1291. then
  1292.     echo shar: error transmitting "'Makefile'" '(should have been 1060 characters)'
  1293. fi
  1294. fi
  1295. if test -f 'bar_graph'
  1296. then
  1297.     echo shar: will not over-write existing file "'bar_graph'"
  1298. else
  1299. echo extracting "'bar_graph'"
  1300. sed 's/^X//' >bar_graph <<'SHAR_EOF'
  1301. X
  1302. XPARM = {{0}}
  1303. X
  1304. Xstep_graph ( PARM ) =
  1305. X    ( sort (PARM [ $0*2+1 , $1 , $3 ]
  1306. X            append
  1307. X        PARM [ $0*2+1 , $2 , $3 ] )
  1308. X    by $1 ) [ $2 , $3 ]
  1309. X
  1310. Xbar_graph ( PARM ) =
  1311. X    ( sort (PARM [ $0*4+1 , $1 , 0 ]
  1312. X            append
  1313. X        PARM [ $0*4+2 , $1 , $3 ]
  1314. X            append
  1315. X        PARM [ $0*4+3 , $2 , $3 ]
  1316. X            append
  1317. X        PARM [ $0*4+4 , $2 , 0 ] )
  1318. X    by $1 ) [ $2 , $3 ]
  1319. X
  1320. SHAR_EOF
  1321. if test 338 -ne "`wc -c < 'bar_graph'`"
  1322. then
  1323.     echo shar: error transmitting "'bar_graph'" '(should have been 338 characters)'
  1324. fi
  1325. fi
  1326. if test -f 'best_fit'
  1327. then
  1328.     echo shar: will not over-write existing file "'best_fit'"
  1329. else
  1330. echo extracting "'best_fit'"
  1331. sed 's/^X//' >best_fit <<'SHAR_EOF'
  1332. X
  1333. XSxy_table = {{0}}
  1334. XSxy( Sxy_table ) =
  1335. X    sum ( Sxy_table[ $1*$2 ] ) - ( 1 / count ( Sxy_table ) )
  1336. X    * sum ( Sxy_table[ $1 ] ) * sum ( Sxy_table [ $2 ] )
  1337. X
  1338. Xbeta_table = {{0}}
  1339. Xbeta_func ( beta_table ) = 
  1340. X    Sxy ( beta_table ) / Sxy ( beta_table[ $1 , $1 ] )
  1341. X
  1342. Xalpha_table = {{0}}
  1343. Xalpha_func ( alpha_table ) =
  1344. X    average ( alpha_table[ $2 ] )
  1345. X    - beta_func ( alpha_table ) * average ( alpha_table[ $1 ] )
  1346. X
  1347. Xfit_Min = 0
  1348. Xfit_Max = 0
  1349. Xfit_Alpha = 0
  1350. Xfit_Beta = 0
  1351. Xline_fit2 ( fit_Min , fit_Max , fit_Alpha , fit_Beta ) =
  1352. X    {{ fit_Min , fit_Alpha + fit_Beta * fit_Min }
  1353. X    {  fit_Max , fit_Alpha + fit_Beta * fit_Max }}
  1354. X
  1355. Xline_fit_table = {{0}}
  1356. Xline_fit ( line_fit_table ) =
  1357. X    line_fit2 ( min ( line_fit_table[ $1 ] ) , max ( line_fit_table[ $1 ] ),
  1358. X    alpha_func ( line_fit_table ) , beta_func ( line_fit_table ) )
  1359. X
  1360. SHAR_EOF
  1361. if test 789 -ne "`wc -c < 'best_fit'`"
  1362. then
  1363.     echo shar: error transmitting "'best_fit'" '(should have been 789 characters)'
  1364. fi
  1365. fi
  1366. if test -f 'graph.h'
  1367. then
  1368.     echo shar: will not over-write existing file "'graph.h'"
  1369. else
  1370. echo extracting "'graph.h'"
  1371. sed 's/^X//' >graph.h <<'SHAR_EOF'
  1372. X/*
  1373. X * Copyright (C) 1986   Alan Kent
  1374. X *
  1375. X * Permission is granted to freely distribute part or
  1376. X * all of this code as long as it is not for profit
  1377. X * and this message is retained in the code.
  1378. X *
  1379. X * No resposibility is taken for any damage or incorect
  1380. X * results this program generates.
  1381. X * 
  1382. X */
  1383. X
  1384. X
  1385. X#define MAX_GRAPHS 30
  1386. X
  1387. Xtypedef struct table_st {
  1388. X    int size;
  1389. X    double *data;
  1390. X    struct table_st *next;
  1391. X} table_st;
  1392. X
  1393. Xtypedef struct tnode_st {
  1394. X    int operator;
  1395. X    struct tnode_st *left , *right;
  1396. X    struct table_st *table;
  1397. X    struct expr_list_st *expr_list;
  1398. X    struct attr_st *expr;
  1399. X    char *ident;
  1400. X    double value;
  1401. X    struct range_st *range;
  1402. X    struct int_st *interval;
  1403. X    int func;
  1404. X    struct parm_st *parm_list;
  1405. X    struct trow_st *const_table;
  1406. X} tnode_st;
  1407. X
  1408. Xtypedef struct attr_st {
  1409. X    double value;
  1410. X    int node_type;
  1411. X    struct attr_st *left , *right;
  1412. X    char *ident;
  1413. X    struct parm_st *parm_list;
  1414. X} attr_st;
  1415. X
  1416. Xtypedef struct expr_list_st {
  1417. X    struct attr_st *expr;
  1418. X    struct expr_list_st *next;
  1419. X} expr_list_st;
  1420. X
  1421. Xtypedef struct range_st {
  1422. X    double min , max;
  1423. X} range_st;
  1424. X
  1425. Xtypedef struct int_st {
  1426. X#define ISIZE    0
  1427. X#define INUMINT    1
  1428. X    int int_type;
  1429. X    double value;
  1430. X} int_st;
  1431. X
  1432. Xtypedef struct graph_st {
  1433. X    int line_type;    /* NO,DOTTED,SOLID,LONGDASHED,SHORTDASHED,DOTDASHED */
  1434. X    int point_type;    /* A mask MSK_TRIANGLE etc */
  1435. X#define MSK_CIRCLE    0x01
  1436. X#define MSK_TRIANGLE    0x02
  1437. X#define MSK_SQUARE    0x04
  1438. X#define MSK_CROSS    0x08
  1439. X#define MSK_PLUS    0x10
  1440. X    int cumulative;    /* true/false */
  1441. X    char *label;
  1442. X    char *legend;    /* NULL means dont put in legend */
  1443. X    table_st *table;
  1444. X} graph_st;
  1445. X
  1446. Xtypedef struct axis_st {
  1447. X    char *format;    /* printf format for numbering axis */
  1448. X    char *user_format;    /* user defined format */
  1449. X    char *label;
  1450. X    int scale;        /* AUTO,NO */
  1451. X    int frame;        /* FRAME,GRID,OUTLINE,NO */
  1452. X    int linear;        /* LOG,LINEAR */
  1453. X    int auto_tick_size;    /* true/false */
  1454. X    range_st range;
  1455. X    int_st *interval;
  1456. X    double tick_size;
  1457. X    double power_10;
  1458. X} axis_st;
  1459. X
  1460. Xtypedef struct parm_st {
  1461. X    int parm_type;
  1462. X    char *ident;
  1463. X    tnode_st *tab_expr;
  1464. X    attr_st *expr;
  1465. X    struct parm_st *next;
  1466. X} parm_st;
  1467. X
  1468. Xtypedef struct tcol_st {
  1469. X    struct attr_st *expr;
  1470. X    struct tcol_st *next;
  1471. X} tcol_st;
  1472. X
  1473. Xtypedef struct trow_st {
  1474. X    struct tcol_st *cols;
  1475. X    struct trow_st *next;
  1476. X} trow_st;
  1477. X
  1478. SHAR_EOF
  1479. if test 2321 -ne "`wc -c < 'graph.h'`"
  1480. then
  1481.     echo shar: error transmitting "'graph.h'" '(should have been 2321 characters)'
  1482. fi
  1483. fi
  1484. if test -f 'yacc.y'
  1485. then
  1486.     echo shar: will not over-write existing file "'yacc.y'"
  1487. else
  1488. echo extracting "'yacc.y'"
  1489. sed 's/^X//' >yacc.y <<'SHAR_EOF'
  1490. X/*
  1491. X * Copyright (C) 1986   Alan Kent
  1492. X *
  1493. X * Permission is granted to freely distribute part or
  1494. X * all of this code as long as it is not for profit
  1495. X * and this message is retained in the code.
  1496. X *
  1497. X * No resposibility is taken for any damage or incorect
  1498. X * results this program generates.
  1499. X * 
  1500. X */
  1501. X
  1502. X
  1503. X/* Declaration section */
  1504. X
  1505. X%{
  1506. X
  1507. X#include <stdio.h>
  1508. X#include <math.h>
  1509. X#include "graph.h"
  1510. X
  1511. X#define LARGE_INT    16000
  1512. X
  1513. Xextern char *new ();
  1514. Xextern double floor ();
  1515. Xextern table_st *read_table ();
  1516. Xextern table_st *load_table ();
  1517. Xextern attr_st *attr_node ();
  1518. Xextern double eval ();
  1519. Xextern table_st *eval_tab ();
  1520. Xextern tnode_st *tab_node ();
  1521. Xextern parm_st *parm_node ();
  1522. Xextern char *ctime ();
  1523. X
  1524. Xextern int gargc;
  1525. Xextern char **gargv;
  1526. Xextern axis_st xaxis;
  1527. Xextern axis_st yaxis;
  1528. Xextern graph_st graph[];
  1529. Xextern int num_graphs;
  1530. Xextern char *graph_label;
  1531. Xextern int horiz_legend;
  1532. Xextern int vert_legend;
  1533. X
  1534. X
  1535. Xstatic axis_st *paxis;
  1536. X
  1537. X
  1538. X%}
  1539. X
  1540. X%union {
  1541. X    attr_st *attr_expr;
  1542. X    table_st *table;
  1543. X    tnode_st *tnode;
  1544. X    double number;
  1545. X    char *string;
  1546. X    expr_list_st *expr_list;
  1547. X    range_st *range;
  1548. X    int_st *interval;
  1549. X    int integer;
  1550. X    parm_st *parm;
  1551. X    tcol_st *tcol;
  1552. X    trow_st *trow;
  1553. X}
  1554. X
  1555. X%left JOIN SORT GROUP CUMULATE
  1556. X%left BY
  1557. X%left APPEND
  1558. X%left ADJACENT
  1559. X%left '[' WHERE
  1560. X%left <string> STRING IDENT TAB_IDENT VAR_IDENT FTAB_IDENT FVAR_IDENT
  1561. X%left <number> NUMBER 
  1562. X
  1563. X%type <string> string_expr string_sub_expr
  1564. X%type <trow> table_line_list
  1565. X%type <tcol> table_line
  1566. X%type <number> constant
  1567. X%type <attr_expr> expr or_op and_op rel_op add_op mul_op primary attr
  1568. X%type <expr_list> expr_list
  1569. X%type <range> range
  1570. X%type <interval> interval
  1571. X%type <string> group_function 
  1572. X%type <tnode> table
  1573. X%type <parm> dec_parm_list dec_parm call_parm_list call_parm
  1574. X
  1575. X%start program
  1576. X
  1577. X%token READ SHELL PRINT TABLE XAXIS YAXIS PLOT GRAPH VALUE INCLUDE
  1578. X%token APPEND SORT JOIN GROUP BY WHERE INTO INTERVAL SIZE FROM TO WITH
  1579. X%token PERFORMING ADJACENT DATE PARAMETER SAVE LOAD AS
  1580. X%token LBRACKET RBRACKET LPAREN RPAREN
  1581. X%token EQ NE GE GT LE LT PLUS MINUS DIVIDE MULTIPLY AND OR NOT NEG
  1582. X%token IDENT TAB_IDENT VAR_IDENT STRING ATTR NUMBER FTAB_IDENT FVAR_IDENT
  1583. X%token TICK LABEL FORMAT AUTO NO SCALE FRAME GRID OUTLINE AXIS 
  1584. X%token LOGRITHMIC LINEAR DOTTED SOLID LONGDASHED SHORTDASHED DOTDASHED LINE
  1585. X%token QUEST COLON MODULUS TAB_CONST PROJECT CUMULATE GENERATE
  1586. X%token TRIANGLE CIRCLE SQUARE CROSS POINTS POWER
  1587. X%token PUT LEGEND AT TOP MIDDLE BOTTOM LEFT CENTER RIGHT
  1588. X%token STR VAL PARMS ASSUME
  1589. X
  1590. X
  1591. X
  1592. X%%
  1593. X
  1594. X/* Rules section */
  1595. X
  1596. X
  1597. Xprogram:    statement_list
  1598. X            {
  1599. X                if ( num_graphs > 0 ) {
  1600. X                dump_graphs ();
  1601. X                reset_graphs ();
  1602. X                }
  1603. X            }
  1604. X    ;
  1605. X
  1606. Xstatement_list:    
  1607. X    |    statement statement_list
  1608. X    ;
  1609. X
  1610. X
  1611. Xstatement:    ';'
  1612. X    |    IDENT EQ table
  1613. X            { tab_declare ( $1 , eval_tab ( $3 ) ); }
  1614. X    |    TAB_IDENT EQ table
  1615. X            { tab_declare ( $1 , eval_tab ( $3 ) ); }
  1616. X    |    IDENT EQ expr
  1617. X            { var_declare ( $1 , eval ( NULL , 0 , $3 ) ); }
  1618. X    |    VAR_IDENT EQ expr
  1619. X            { var_declare ( $1 , eval ( NULL , 0 , $3 ) ); }
  1620. X    |    IDENT '(' dec_parm_list ')' EQ expr
  1621. X            { fun_declare ( $1 , $3 , $6 , NULL ); }
  1622. X    |    IDENT '(' dec_parm_list ')' EQ table
  1623. X            { fun_declare ( $1 , $3 , NULL , $6 ); }
  1624. X    |    INCLUDE string_expr
  1625. X            { include ( $2 ); release ( $2 ); }
  1626. X    |    SHELL string_expr
  1627. X            { system ( $2 ); /* use >file */ release ( $2 ); }
  1628. X    |    SAVE table AS string_expr
  1629. X            { save_table ( $4 , eval_tab ( $2 ) ); release ( $4 ); }
  1630. X    |    PRINT GT GT string_expr table
  1631. X            { print_table ( eval_tab ( $5 ) , $4 , "a" ); release ( $4 ); }
  1632. X    |    PRINT GT string_expr table
  1633. X            { print_table ( eval_tab ( $4 ) , $3 , "w" ); release ( $3 ); }
  1634. X    |    PRINT table
  1635. X            { print_table ( eval_tab ( $2 ) , NULL , NULL ); }
  1636. X    |    PRINT GT GT string_expr expr
  1637. X            { print_expr ( eval ( NULL , 0 , $5 ) , $4 , "a" ); release ( $4 ); }
  1638. X    |    PRINT GT string_expr expr
  1639. X            { print_expr ( eval ( NULL , 0 , $4 ) , $3 , "w" ); release ( $3 ); }
  1640. X    |    PRINT expr
  1641. X            { print_expr ( eval ( NULL , 0 , $2 ) , NULL , NULL ); }
  1642. X    |    PRINT GT GT string_expr string_expr
  1643. X            { print_string ( $5 , $4 , "a" ); release ( $4 ); release ( $5 ); }
  1644. X    |    PRINT GT string_expr string_expr
  1645. X            { print_string ( $4 , $3 , "w" ); release ( $3 ); release ( $4 ); }
  1646. X    |    PRINT string_expr
  1647. X            { print_string ( $2 , NULL , NULL ); release ( $2 ); }
  1648. X    |    graph
  1649. X    |    XAXIS
  1650. X            { paxis = &xaxis; }
  1651. X        axis
  1652. X    |    YAXIS
  1653. X            { paxis = &yaxis; }
  1654. X        axis
  1655. X    |    PUT LEGEND AT pos_list
  1656. X    |    PLOT
  1657. X            { dump_graphs (); reset_graphs (); }
  1658. X    |    ASSUME expr string_expr
  1659. X            {
  1660. X                if ( eval ( NULL , 0 , $2 ) == 0.0 ) {
  1661. X                fprintf ( stderr , "%s\n" , $3 );
  1662. X                exit ( 1 );
  1663. X                }
  1664. X                release ( $3 );
  1665. X            }
  1666. X    ;
  1667. X
  1668. Xpos_list:    /* empty */
  1669. X    |    pos pos_list
  1670. X    ;
  1671. X
  1672. Xpos:        LEFT
  1673. X            { horiz_legend = LEFT; }
  1674. X    |    CENTER
  1675. X            { horiz_legend = CENTER; }
  1676. X    |    RIGHT
  1677. X            { horiz_legend = RIGHT; }
  1678. X    |    TOP
  1679. X            { vert_legend = TOP; }
  1680. X    |    MIDDLE
  1681. X            { vert_legend = MIDDLE; }
  1682. X    |    BOTTOM
  1683. X            { vert_legend = BOTTOM; }
  1684. X    ;
  1685. X
  1686. Xtable    :    READ string_expr
  1687. X            {
  1688. X                $$ = tab_node ( TAB_CONST );
  1689. X                $$->table = read_table ( $2 , -1 , -1 );
  1690. X                release ( $2 );
  1691. X            }
  1692. X    |    READ expr BY expr string_expr
  1693. X            {
  1694. X                $$ = tab_node ( TAB_CONST );
  1695. X                $$->table = read_table ( $5 ,
  1696. X                    (int)eval ( NULL , 0 , $2 ) ,
  1697. X                    (int)eval ( NULL , 0 , $4 ) );
  1698. X                release ( $5 );
  1699. X            }
  1700. X    |    LOAD string_expr
  1701. X            {
  1702. X                $$ = tab_node ( TAB_CONST );
  1703. X                $$->table = load_table ( $2 );
  1704. X                release ( $2 );
  1705. X            }
  1706. X    |    '{' table_line_list '}'
  1707. X            {
  1708. X                $$ = tab_node ( TABLE );
  1709. X                $$->const_table = $2;
  1710. X            }
  1711. X    |    GENERATE range interval
  1712. X            {
  1713. X                $$ = tab_node ( GENERATE );
  1714. X                $$->range = $2;
  1715. X                $$->interval = $3;
  1716. X            }
  1717. X    |    table APPEND table
  1718. X            {
  1719. X                $$ = tab_node ( APPEND );
  1720. X                $$->left = $1;
  1721. X                $$->right = $3;
  1722. X            }
  1723. X    |    table ADJACENT table
  1724. X            {
  1725. X                $$ = tab_node ( ADJACENT );
  1726. X                $$->left = $1;
  1727. X                $$->right = $3;
  1728. X            }
  1729. X    |    table '[' expr_list ']'
  1730. X            {
  1731. X                $$ = tab_node ( PROJECT );
  1732. X                $$->left = $1;
  1733. X                $$->expr_list = $3;
  1734. X            }
  1735. X    |    table WHERE expr
  1736. X            {
  1737. X                $$ = tab_node ( WHERE );
  1738. X                $$->left = $1;
  1739. X                $$->expr = $3;
  1740. X            }
  1741. X    |    SORT table BY attr
  1742. X            {
  1743. X                $$ = tab_node ( SORT );
  1744. X                $$->left = $2;
  1745. X                $$->expr = $4;
  1746. X            }
  1747. X    |    JOIN table ',' table BY attr ',' attr
  1748. X            {
  1749. X                $$ = tab_node ( JOIN );
  1750. X                $$->left = $2;
  1751. X                $$->right = $4;
  1752. X                $$->expr = attr_node ( JOIN , (double)0.0 , $6 , $8 );
  1753. X            }
  1754. X    |    CUMULATE table BY attr
  1755. X            {
  1756. X                $$ = tab_node ( CUMULATE );
  1757. X                $$->left = $2;
  1758. X                $$->expr = $4;
  1759. X            }
  1760. X    |    GROUP table range interval PERFORMING group_function
  1761. X            {
  1762. X                $$ = tab_node ( GROUP );
  1763. X                $$->left = $2;
  1764. X                $$->range = $3;
  1765. X                $$->interval = $4;
  1766. X                $$->ident = $6;
  1767. X            }
  1768. X    |    '(' table ')'
  1769. X            { $$ = $2; }
  1770. X    |    IDENT
  1771. X            { abort ( "Undefined identifier" ); }
  1772. X    |    FTAB_IDENT '(' call_parm_list ')'
  1773. X            {
  1774. X                $$ = tab_node ( FTAB_IDENT );
  1775. X                $$->ident = $1;
  1776. X                $$->parm_list = $3;
  1777. X            }
  1778. X    |    TAB_IDENT
  1779. X            { $$ = tab_node ( TAB_IDENT ); $$->ident = $1; }
  1780. X    ;
  1781. X
  1782. Xgroup_function:
  1783. X        FVAR_IDENT
  1784. X            { $$ = $1; check_group_fun ( $1 ); }
  1785. X    ;
  1786. X
  1787. Xtable_line_list:    
  1788. X            { $$ = NULL; }
  1789. X    |    '{' table_line '}' table_line_list
  1790. X            {
  1791. X                $$ = (trow_st *) new ( sizeof ( trow_st ) );
  1792. X                $$->cols = $2;
  1793. X                $$->next = $4;
  1794. X            }
  1795. X    ;
  1796. X
  1797. Xtable_line:    expr
  1798. X            {
  1799. X                $$ = (tcol_st *) new ( sizeof ( tcol_st ) );
  1800. X                $$->expr = $1;
  1801. X                $$->next = NULL;
  1802. X            }
  1803. X    |
  1804. X        expr ',' table_line
  1805. X            {
  1806. X                $$ = (tcol_st *) new ( sizeof ( tcol_st ) );
  1807. X                $$->expr = $1;
  1808. X                $$->next = $3;
  1809. X            }
  1810. X    ;
  1811. X
  1812. Xattr    :    '$' primary
  1813. X            { $$ = $2; }
  1814. X    ;
  1815. X
  1816. Xexpr    :    or_op '?' or_op ':' or_op
  1817. X            { $$ = attr_node ( QUEST , (double)0.0 , $1 ,
  1818. X                attr_node ( COLON , (double)0.0 , $3 , $5 ) ); }
  1819. X    |    or_op
  1820. X            { $$ = $1; }
  1821. X    ;
  1822. X
  1823. Xor_op    :    and_op '|' or_op
  1824. X            { $$ = attr_node ( OR , (double)0.0 , $1 , $3 ); }
  1825. X    |    and_op
  1826. X            { $$ = $1; }
  1827. X    ;
  1828. X
  1829. Xand_op    :    rel_op '&' and_op
  1830. X            { $$ = attr_node ( AND , (double)0.0 , $1 , $3 ); }
  1831. X    |    rel_op
  1832. X            { $$ = $1; }
  1833. X    ;
  1834. X
  1835. Xrel_op    :    add_op EQ add_op
  1836. X            { $$ = attr_node ( EQ , (double)0.0 , $1 , $3 ); }
  1837. X    |    add_op NE add_op
  1838. X            { $$ = attr_node ( NE , (double)0.0 , $1 , $3 ); }
  1839. X    |    add_op LE add_op
  1840. X            { $$ = attr_node ( LE , (double)0.0 , $1 , $3 ); }
  1841. X    |    add_op LT add_op
  1842. X            { $$ = attr_node ( LT , (double)0.0 , $1 , $3 ); }
  1843. X    |    add_op GE add_op
  1844. X            { $$ = attr_node ( GE , (double)0.0 , $1 , $3 ); }
  1845. X    |    add_op GT add_op
  1846. X            { $$ = attr_node ( GT , (double)0.0 , $1 , $3 ); }
  1847. X    |    add_op
  1848. X            { $$ = $1; }
  1849. X    ;
  1850. X
  1851. Xadd_op    :    mul_op '+' add_op
  1852. X            { $$ = attr_node ( PLUS , (double)0.0 , $1 , $3 ); }
  1853. X    |    mul_op '-' add_op
  1854. X            { $$ = attr_node ( MINUS , (double)0.0 , $1 , $3 ); }
  1855. X    |    mul_op
  1856. X            { $$ = $1; }
  1857. X    ;
  1858. X
  1859. Xmul_op    :    primary '/' mul_op
  1860. X            { $$ = attr_node ( DIVIDE , (double)0.0 , $1 , $3 ); }
  1861. X    |    primary '*' mul_op
  1862. X            { $$ = attr_node ( MULTIPLY , (double)0.0 , $1 , $3 ); }
  1863. X    |    primary '%' mul_op
  1864. X            { $$ = attr_node ( MODULUS , (double)0.0 , $1 , $3 ); }
  1865. X    |    primary
  1866. X            { $$ = $1; }
  1867. X    ;
  1868. X
  1869. Xprimary    :    '-' primary
  1870. X            { $$ = attr_node ( NEG , (double)0.0 , $2 , NULL ); }
  1871. X    |    '!' primary
  1872. X            { $$ = attr_node ( NOT , (double)0.0 , $2 , NULL ); }
  1873. X    |    '(' expr ')'
  1874. X            { $$ = $2; }
  1875. X    |    attr
  1876. X            { $$ = attr_node ( ATTR , (double)0.0 , $1 , NULL ); }
  1877. X    |    constant
  1878. X            { $$ = attr_node ( NUMBER , $1 , NULL , NULL ); }
  1879. X    |    FVAR_IDENT '(' call_parm_list ')'
  1880. X            {
  1881. X                $$ = attr_node ( FVAR_IDENT , (double)0.0 , NULL , NULL );
  1882. X                $$->ident = $1;
  1883. X                $$->parm_list = $3;
  1884. X            }
  1885. X    |    VAR_IDENT
  1886. X            {
  1887. X                $$ = attr_node ( VAR_IDENT , (double)0.0 , NULL , NULL );
  1888. X                $$->ident = $1;
  1889. X            }
  1890. X    ;
  1891. X
  1892. Xexpr_list:    
  1893. X            { $$ = NULL; }
  1894. X    |    expr
  1895. X            {
  1896. X                $$ = (expr_list_st *) new ( sizeof ( expr_list_st ) );
  1897. X                $$->expr = $1;
  1898. X                $$->next = NULL;
  1899. X            }
  1900. X    |    expr ',' expr_list
  1901. X            {
  1902. X                $$ = (expr_list_st *) new ( sizeof ( expr_list_st ) );
  1903. X                $$->expr = $1;
  1904. X                $$->next = $3;
  1905. X            }
  1906. X    ;
  1907. X
  1908. Xinterval:    WITH expr INTERVAL 
  1909. X            {
  1910. X                $$ = (int_st *) new ( sizeof ( int_st ) );
  1911. X                $$->int_type = INUMINT;
  1912. X                $$->value = eval ( NULL , 0 , $2 );
  1913. X            }
  1914. X    |    INTERVAL SIZE expr 
  1915. X            {
  1916. X                $$ = (int_st *) new ( sizeof ( int_st ) );
  1917. X                $$->int_type = ISIZE;
  1918. X                $$->value = eval ( NULL , 0 , $3 );
  1919. X            }
  1920. X    ;
  1921. X
  1922. Xrange    :    /* default min to max */
  1923. X            { $$ = NULL; }
  1924. X    |    FROM expr TO expr
  1925. X            {
  1926. X                $$ = (range_st *) new ( sizeof ( range_st ) );
  1927. X                $$->min = eval ( NULL , 0 , $2 );
  1928. X                $$->max = eval ( NULL , 0 , $4 );
  1929. X            }
  1930. X    ;
  1931. X
  1932. Xconstant:    NUMBER
  1933. X            { $$ = $1; }
  1934. X    |    PARMS
  1935. X            { $$ = gargc - 2; }
  1936. X    |    VAL '(' string_expr ')'
  1937. X            {
  1938. X                double num;
  1939. X
  1940. X                if ( scan_value ( $3 , &num ) == NULL ) {
  1941. X                warn ( "Illegal number in VAL()" );
  1942. X                num = 0.0;
  1943. X                }
  1944. X                release ( $3 );
  1945. X                $$ = num;
  1946. X            }
  1947. X    ;
  1948. X
  1949. Xaxis    :    axis_option_list
  1950. X    ;
  1951. X
  1952. Xaxis_option_list:
  1953. X    |    axis_option axis_option_list
  1954. X    ;
  1955. X
  1956. Xaxis_option:
  1957. X    /*
  1958. X    |    TICK range
  1959. X    |    AUTO TICK
  1960. X    */
  1961. X        LABEL string_expr
  1962. X            { paxis->label = $2; }
  1963. X    |    FORMAT string_expr
  1964. X            { paxis->user_format = $2; }
  1965. X    |    AUTO SCALE
  1966. X            { paxis->scale = AUTO; }
  1967. X    |    NO SCALE
  1968. X            { paxis->scale = NO; }
  1969. X    |    TICK SIZE expr POWER expr
  1970. X            {
  1971. X                paxis->auto_tick_size = 0;
  1972. X                paxis->tick_size = eval ( NULL , 0 , $3 );
  1973. X                paxis->power_10 = eval ( NULL , 0 , $5 );
  1974. X            }
  1975. X    |    TICK SIZE expr
  1976. X            {
  1977. X                paxis->auto_tick_size = 0;
  1978. X                paxis->tick_size = eval ( NULL , 0 , $3 );
  1979. X                paxis->power_10 = 0.0;    /* not good */
  1980. X            }
  1981. X    |    FRAME AXIS
  1982. X            { paxis->frame = FRAME; }
  1983. X    |    GRID AXIS
  1984. X            { paxis->frame = GRID; }
  1985. X    |    OUTLINE AXIS
  1986. X            { paxis->frame = OUTLINE; }
  1987. X    |    NO AXIS
  1988. X            { paxis->frame = NO; }
  1989. X    |    LOGRITHMIC
  1990. X            { paxis->linear = LOGRITHMIC; }
  1991. X    |    LINEAR
  1992. X            { paxis->linear = LINEAR; }
  1993. X    |    FROM expr TO expr
  1994. X            {
  1995. X                paxis->range.min = eval ( NULL , 0 , $2 );
  1996. X                paxis->range.max = eval ( NULL , 0 , $4 );
  1997. X            }
  1998. X    ;
  1999. X
  2000. Xgraph    :    GRAPH table
  2001. X            {
  2002. X                if ( num_graphs >= MAX_GRAPHS )
  2003. X                abort ( "too many graphs" );
  2004. X                graph[ num_graphs ].line_type = SOLID;
  2005. X                graph[ num_graphs ].point_type = 0;
  2006. X                graph[ num_graphs ].cumulative = 0;
  2007. X                graph[ num_graphs ].label = NULL;
  2008. X                graph[ num_graphs ].legend = NULL;
  2009. X            }
  2010. X        graph_option_list
  2011. X            {
  2012. X                table_st *p;
  2013. X
  2014. X                p = eval_tab ( $2 );
  2015. X                if ( p == NULL || p->next == NULL )
  2016. X                abort ( "GRAPH requires two column tables to plot" );
  2017. X                if ( p->size < 1 )
  2018. X                warn ( "No data in graph to plot" );
  2019. X                else
  2020. X                graph[ num_graphs++ ].table = p;
  2021. X            }
  2022. X    |    GRAPH LABEL string_expr
  2023. X            {
  2024. X                graph_label = $3;
  2025. X            }
  2026. X    ;
  2027. X
  2028. Xgraph_option_list:
  2029. X    |    graph_option_list graph_option
  2030. X    ;
  2031. X
  2032. Xgraph_option:    DOTTED LINE
  2033. X            { graph[ num_graphs ].line_type = DOTTED; }
  2034. X    |    SOLID LINE
  2035. X            { graph[ num_graphs ].line_type = SOLID; }
  2036. X    |    SHORTDASHED LINE
  2037. X            { graph[ num_graphs ].line_type = SHORTDASHED; }
  2038. X    |    LONGDASHED LINE
  2039. X            { graph[ num_graphs ].line_type = LONGDASHED; }
  2040. X    |    DOTDASHED LINE
  2041. X            { graph[ num_graphs ].line_type = DOTDASHED; }
  2042. X    |    NO LINE
  2043. X            { graph[ num_graphs ].line_type = NO; }
  2044. X    |    NO POINTS
  2045. X            { graph[ num_graphs ].point_type = 0; }
  2046. X    |    TRIANGLE POINTS
  2047. X            { graph[ num_graphs ].point_type |= MSK_TRIANGLE; }
  2048. X    |    CIRCLE POINTS
  2049. X            { graph[ num_graphs ].point_type |= MSK_CIRCLE; }
  2050. X    |    SQUARE POINTS
  2051. X            { graph[ num_graphs ].point_type |= MSK_SQUARE; }
  2052. X    |    CROSS POINTS
  2053. X            { graph[ num_graphs ].point_type |= MSK_CROSS; }
  2054. X    |    PLUS POINTS
  2055. X            { graph[ num_graphs ].point_type |= MSK_PLUS; }
  2056. X    |    LABEL string_expr
  2057. X            { graph[ num_graphs ].label = $2; }
  2058. X    |    LEGEND string_expr
  2059. X            { graph[ num_graphs ].legend = $2; }
  2060. X    ;
  2061. X
  2062. Xdec_parm_list:    
  2063. X            { $$ = NULL; }
  2064. X    |
  2065. X        dec_parm
  2066. X            { $$ = $1; $$->next = NULL; }
  2067. X    |    dec_parm ',' dec_parm_list
  2068. X            { $$ = $1; $$->next = $3; }
  2069. X    ;
  2070. X
  2071. Xdec_parm:    VAR_IDENT
  2072. X            { $$ = parm_node ( $1 , VALUE ); }
  2073. X    |    TAB_IDENT
  2074. X            { $$ = parm_node ( $1 , TABLE ); }
  2075. X    ;
  2076. X
  2077. Xcall_parm_list:    
  2078. X            { $$ = NULL; }
  2079. X    |
  2080. X        call_parm
  2081. X            { $$ = $1; $$->next = NULL; }
  2082. X    |    call_parm ',' call_parm_list
  2083. X            { $$ = $1; $$->next = $3; }
  2084. X    ;
  2085. X
  2086. Xcall_parm:    expr
  2087. X            { $$ = parm_node ( NULL , VALUE ); $$->expr = $1; }
  2088. X    |    table
  2089. X            { $$ = parm_node ( NULL , TABLE ); $$->tab_expr = $1; }
  2090. X    ;
  2091. X
  2092. Xstring_expr:    string_sub_expr
  2093. X            {
  2094. X                $$ = $1;
  2095. X            }
  2096. X    |    string_sub_expr '+' string_expr
  2097. X            {
  2098. X                char *p;
  2099. X
  2100. X                p = new ( strlen ( $1 ) + strlen ( $3 ) + 1 );
  2101. X                strcpy ( p , $1 );
  2102. X                strcat ( p , $3 );
  2103. X                release ( $1 );
  2104. X                release ( $3 );
  2105. X                $$ = p;
  2106. X            }
  2107. X    ;
  2108. X
  2109. Xstring_sub_expr: STRING
  2110. X            {
  2111. X                char *p;
  2112. X
  2113. X                p = new ( strlen ( $1 ) + 1 );
  2114. X                strcpy ( p , $1 );
  2115. X                $$ = p;
  2116. X            }
  2117. X    |    PARAMETER constant
  2118. X            {
  2119. X                char *p;
  2120. X                int i;
  2121. X
  2122. X                i = $2;
  2123. X                if ( i > gargc - 2  ||  i < 1 )
  2124. X                abort ( "undefined parameter" );
  2125. X                p = new ( strlen ( gargv[ i + 1 ] ) + 1 );
  2126. X                strcpy ( p , gargv[ i + 1 ] );
  2127. X                $$ = p;
  2128. X            }
  2129. X    |    STR '(' string_expr ',' expr ')'
  2130. X            {
  2131. X                char *p;
  2132. X                char buf[ 100 ];
  2133. X
  2134. X                sprintf ( buf , $3 , eval ( NULL , 0 , $5 ) );
  2135. X                p = new ( strlen ( buf ) + 1 );
  2136. X                strcpy ( p , buf );
  2137. X                release ( $3 );
  2138. X                $$ = p;
  2139. X            }
  2140. X    |    STR '(' expr ')'
  2141. X            {
  2142. X                char *p;
  2143. X                char buf[ 30 ];
  2144. X
  2145. X                sprintf ( buf , "%g" , eval ( NULL , 0 , $3 ) );
  2146. X                p = new ( strlen ( buf ) + 1 );
  2147. X                strcpy ( p , buf );
  2148. X                $$ = p;
  2149. X            }
  2150. X    |    DATE
  2151. X            {
  2152. X                long clock;
  2153. X                char *p , *str;
  2154. X                int i;
  2155. X
  2156. X                p = new ( 32 );
  2157. X                time ( &clock );
  2158. X                str = ctime ( &clock );
  2159. X                for ( i = 0; str[i] != '\n' && str[i] != '\0'; i++ )
  2160. X                p[i] = str[i];
  2161. X                p[i] = '\0';
  2162. X                $$ = p;
  2163. X            }
  2164. X    ;
  2165. X
  2166. X%%
  2167. X
  2168. X/* Subroutine section */
  2169. X
  2170. SHAR_EOF
  2171. if test 15119 -ne "`wc -c < 'yacc.y'`"
  2172. then
  2173.     echo shar: error transmitting "'yacc.y'" '(should have been 15119 characters)'
  2174. fi
  2175. fi
  2176. # end of shell archive
  2177. exit 0
  2178.